home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
demos
/
video
/
bigvideoin.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
9KB
|
358 lines
/*
* Copyright (C) 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* File: bigvideoin
*
* Usage: bigvideoin [-b] [-p] [-h]
*
* Description: bigvideoin demonstrates zoomed videoin inside a large window.
* This application only runs on video hardware
* that has a video output port. It will not run
* on a VINO video board.
*
* sort of a hybrid of simple2vs and videoin.
* last modified 2/28/94 atang
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <Xm/MwmUtil.h>
#include <X11/Xutil.h>
#include <vl/vl.h>
/* defines */
#define ESC_KEY '\006'
#define USAGE \
"%s: [-b] [-h]\n\
\t-b\tno window borders\n\
\t-p x y\twindow position (must be last option if specified)\n\
\t-h\tthis help message\n"
/* function prototypes */
void VideoTracking(Window, int,int);
void processXEvent(uint, void *);
void processVLEvent(VLServer, VLEvent *, void *);
void docleanup(void);
void noborders(Display *, Window);
/* globals */
VLServer svr;
VLPath path;
Display *dpy;
Window vwin;
VLNode src, drn;
int win_border = True;
int init_position = False;
char *_progname;
int init_x = 0;
int init_y = 0;
int input_timing;
Atom WM_DELETE_WINDOW;
Atom WM_PROTOCOLS;
/*
* Set the window property telling motif-compatible window
* managers (e.g., 4Dwm) to not put any border on this window.
*/
void
noborders(Display *display, Window win)
{
MwmHints mwmhints;
Atom MOTIF_WM_HINTS;
mwmhints.flags = MWM_HINTS_DECORATIONS;
mwmhints.decorations = 0 /* MWM_DECOR_BORDER */;
MOTIF_WM_HINTS = XInternAtom(display, "_MOTIF_WM_HINTS", False);
XChangeProperty(display, win, MOTIF_WM_HINTS, MOTIF_WM_HINTS,
sizeof(long)*8, PropModeReplace,
(unsigned char*) &mwmhints,
sizeof(mwmhints) / sizeof(long));
}
main(int argc, char **argv)
{
VLControlValue val;
int x, y, c, win_x,win_y;
uint w, h, bw, d;
Window dummyWin;
XSizeHints size_hints;
Atom WM_PROT_SET[2];
Atom _SGI_VIDEO;
_progname = argv[0];
while ((c = getopt(argc, argv, "hbp")) != EOF)
{
switch(c)
{
case 'b':
win_border = 0;
break;
case 'h':
fprintf(stderr, USAGE, _progname);
exit(0);
break;
case 'p':
init_x = atoi(argv[optind-1]);
init_y = atoi(argv[optind]);
if ((init_y < 0) || (init_x < 0))
{
fprintf(stderr,
"%s: x and y coordinates must be non-negative.\n",
_progname);
opterr = 1;
}
init_position = 1;
break;
}
}
/* Open an X display */
if (!(dpy = XOpenDisplay("")))
exit(1);
/* Connect to the video daemon */
if (!(svr = vlOpenVideo("")))
exit(1);
/* Create a source node on a video device */
src = vlGetNode(svr, VL_SRC, VL_VIDEO, VL_ANY);
/* Create a drain node on the screen */
drn = vlGetNode(svr, VL_DRN, VL_SCREEN, VL_ANY);
/* Create a path on the first device that supports it */
if((path = vlCreatePath(svr, VL_ANY, src, drn)) < 0)
exit(1);
/* Set up the hardware for and define the usage of the path */
vlSetupPaths(svr, (VLPathList)&path, 1, VL_SHARE, VL_SHARE);
/* get the current input timing */
vlGetControl(svr, path, src, VL_TIMING, &val);
input_timing = val.intVal;
/* size considerations */
vlGetControl(svr, path, drn, VL_SIZE, &val);
x = val.xyVal.x;
y = val.xyVal.y;
if ((input_timing == VL_TIMING_625_SQ_PIX) ||
(input_timing == VL_TIMING_625_4FSC))
{/* PAL */
win_x = 1280;
win_y = 1020;
}else
{/* NTSC */
win_x = 1280;
win_y = 972;
}
/* Get the window's origin */
vlGetControl(svr, path, drn, VL_ORIGIN, &val);
x = val.xyVal.x;
y = val.xyVal.y;
/* If user requested initial window position */
if (init_position)
{
x = init_x;
y = init_y;
}
vwin = XCreateWindow(dpy, RootWindow(dpy, 0), x, y, win_x, win_y, 0,
CopyFromParent, CopyFromParent, CopyFromParent,
(ulong) 0, NULL);
_SGI_VIDEO = XInternAtom(dpy, "_SGI_VIDEO", False);
WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
WM_PROTOCOLS = XInternAtom(dpy, "WM_PROTOCOLS", False);
WM_PROT_SET[0] = WM_DELETE_WINDOW;
WM_PROT_SET[1] = _SGI_VIDEO;
XSetWMProtocols(dpy,vwin, WM_PROT_SET, 2);
XStoreName(dpy, vwin, "video input");
/* If the user requested no window borders kill the borders */
if (!win_border)
noborders(dpy, vwin);
/* Ignore window manager placement set the window to 10, 10 */
size_hints.flags = USPosition;
size_hints.x = 10;
size_hints.y = 10;
XSetWMNormalHints(dpy, vwin, &size_hints);
XMapWindow(dpy, vwin);
XSelectInput(dpy, vwin, KeyPressMask|VisibilityChangeMask
|ExposureMask|StructureNotifyMask);
XSync(dpy, 0);
/* Set up zoom factor*/
val.fractVal.numerator = 2;
val.fractVal.denominator = 1;
vlSetControl(svr, path, drn, VL_ZOOM, &val);
/* Set the X window to be the drain */
val.intVal = vwin;
vlSetControl(svr, path, drn, VL_WINDOW, &val);
/* Get X and VL into the same coordinate system */
XTranslateCoordinates(dpy, vwin, RootWindow(dpy, DefaultScreen(dpy)),
0, 0,&x, &y, &dummyWin);
/* Set the live video to the same location and size as the X window */
val.xyVal.x = x;
val.xyVal.y = y;
vlSetControl(svr, path, drn, VL_ORIGIN, &val);
XGetGeometry(dpy, vwin, &dummyWin, &x, &y, &w, &h, &bw, &d);
val.xyVal.x = w;
val.xyVal.y = h;
vlSetControl(svr, path, drn, VL_SIZE, &val);
/* allow for X event processing */
vlRegisterHandler(svr, ConnectionNumber(dpy), processXEvent,
(VLPendingFunc)XPending, dpy);
/* Set up event handler routine as callback for all events */
vlAddCallback(svr, path, VLAllEventsMask, processVLEvent, NULL);
/* Set the VL event mask so we only get control changed events */
vlSelectEvents(svr, path, VLControlChangedMask);
/* Begin the data transfer */
vlBeginTransfer(svr, path, 0, NULL);
vlMainLoop();
}
/*
* VideoTracking - if the user changes the size of the window,
* update the video to reflect the new size and position.
*/
void
VideoTracking(Window win, int x, int y)
{
Window dummyWin;
VLControlValue val;
/* Get X's idea of origin */
XTranslateCoordinates(dpy, win, RootWindow(dpy, DefaultScreen(dpy)),
0, 0,
&x, &y,
&dummyWin);
/* Try to make vl match X */
val.xyVal.x = x;
val.xyVal.y = y;
vlSetControl(svr, path, drn, VL_ORIGIN, &val);
}
/*
* VLEvent processing for video to screen.
* We only deal with control changed events.
*/
void
processVLEvent(VLServer vlSvr, VLEvent *ev, void *dummy)
{
VLControlChangedEvent *cev = (VLControlChangedEvent *) ev;
VLControlValue val;
switch (ev->reason)
{ /* Ignore all but a change in the drain's location */
case VLControlChanged:
if ((cev->type == VL_ORIGIN)&&(cev->node == drn))
{
/* Drain moved, move window accordingly */
vlGetControl(svr, path, drn, VL_ORIGIN, &val);
XMoveWindow(dpy, vwin, val.xyVal.x, val.xyVal.y);
}
break;
}
}
/* XEvent processing for video to screen */
void
processXEvent(uint fd, void *source)
{
int i;
if (source == (caddr_t)dpy)
{
XEvent ev;
XNextEvent(dpy, &ev);
switch (ev.type)
{
case ClientMessage:
if (ev.xclient.message_type == WM_PROTOCOLS)
if (ev.xclient.data.l[0] == WM_DELETE_WINDOW)
docleanup();
break;
case Expose: /* These really don't affect us */
case GraphicsExpose:
case VisibilityNotify:
break;
case ConfigureNotify: /* Window moved or changed size */
VideoTracking(ev.xany.window, ev.xconfigure.x,ev.xconfigure.y);
break;
case KeyPress:
{
XKeyEvent *kev = (XKeyEvent *)&ev;
KeySym keysym;
char buf[4];
XLookupString(kev, buf, 1, &keysym, 0);
switch (buf[0])
{ /* Quit */
case 'q':
case 'Q':
case ESC_KEY:
docleanup();
break;
default:
break;
}
}
}
}
}
/* Dispose of the vl structures */
void
docleanup()
{ /* End the data transfer */
vlEndTransfer(svr, path);
/* Destroy the path, free it's memory */
vlDestroyPath(svr, path);
/* Disonnect from the daemon */
vlCloseVideo(svr);
exit(0);
}